package br.usp.icmc.dilvan.aimTemplateViewer.client.impl;

import br.usp.icmc.dilvan.aimTemplateViewer.client.ComponentAIM;
import br.usp.icmc.dilvan.aimTemplateViewer.client.aimTemplate.AllowedTermAIMTemplate;
import br.usp.icmc.dilvan.aimTemplateViewer.client.aimTemplate.AnatomicEntityAIMTemplate;
import br.usp.icmc.dilvan.aimTemplateViewer.client.aimTemplate.AnatomicEntityCharacteristicAIMTemplate;
import br.usp.icmc.dilvan.aimTemplateViewer.client.aimTemplate.CalculationTypeAIMTemplate;
import br.usp.icmc.dilvan.aimTemplateViewer.client.aimTemplate.ComponentAIMTemplate;
import br.usp.icmc.dilvan.aimTemplateViewer.client.aimTemplate.ImagingObservationAIMTemplate;
import br.usp.icmc.dilvan.aimTemplateViewer.client.aimTemplate.ImagingObservationCharacteristicAIMTemplate;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class ComponentAIMImpl extends Composite  implements ComponentAIM {
	int itemNumber = 0;
	VerticalPanel panel = new VerticalPanel();

	private final ComponentAIMTemplate result = new ComponentAIMTemplate();
	
	private final String FIRSTELEMENT = "---";

	private static ComponentAIMUiBinder uiBinder = GWT
			.create(ComponentAIMUiBinder.class);
	@UiField
	CaptionPanel captionPanel;
	Presenter presenter;
	
	interface ComponentAIMUiBinder extends UiBinder<Widget, ComponentAIMImpl> {
	}

	public ComponentAIMImpl() {
		initWidget(uiBinder.createAndBindUi(this));
	}

	public ComponentAIMImpl(ComponentAIMTemplate componet) {
		initWidget(uiBinder.createAndBindUi(this));
		// set the item Number
		itemNumber = componet.getItemNumber();
		// set the caption for the component
		captionPanel.setCaptionHTML(componet.getLabel());
		captionPanel.add(panel);
		// call creation for QuestionType
		createQuestionType(componet.getQuestionType());
		// call creation for Allowed forms widgets
		createAllowedTerm(componet);
		//
//		createAnatomicEntity(componet.getAnatomicEntityAIMTemplate());
		//
		createImageObservation(componet.getImagingObservationAIMTemplate());
		//
		createCalculation(componet.getCalculation());
		//
		createInference();
		//
		createGeometricShape();
	}

	@Override
	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}
	
	public ComponentAIMTemplate getResult() {
		return result;
	}
	
	public boolean isCompleteAnnotation(){
		return false;
	}
	
	public void createQuestionType(AllowedTermAIMTemplate a) {
		if (a == null)
			return;
		CaptionPanel c = new CaptionPanel("Question Type");
		c.add(new Label(a.getCodeMeaning()));
		c.setStyleName("captionComponent");
		panel.add(c);
	}

	@SuppressWarnings("deprecation")
	public void createAllowedTerm(final ComponentAIMTemplate componet) {
		final ListBox list = new ListBox();
		if (componet.getMaxCardinality() > 1)
			list.setMultipleSelect(true);// this way allow to the multiple selection
		// create a first element
		list.addItem(FIRSTELEMENT);
		for (AllowedTermAIMTemplate a : componet.getAllowedTerms()) {
			list.addItem(a.getCodeMeaning(), a.getCodeValue());
		}
		// if the component don't have a select interface
		if (componet.getAllowedTerms().size() > 0)
			panel.add(list);

		// add handler for change the result model
		list.addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				//cleaning the old selected values
				result.getAllowedTerms().clear();
				//check if the selected value was a empty value
				if (list.getSelectedIndex() != 0){
				//	result.getResponseTemplate().getAllowedTerms().add(new AllowedTermAIMTemplate(componet.getAllowedTerms().get(list.getSelectedIndex()-1).getCodeMeaning(), componet.getAllowedTerms().get(list.getSelectedIndex()-1).getCodeValue(), componet.getAllowedTerms().get(list.getSelectedIndex()-1).getCodingSchemeDesignator()));
					result.getAllowedTerms().add(componet.getAllowedTerms().get(list.getSelectedIndex()-1));
				//	Window.alert(result.getAllowedTerms().get(0).getCodeValue());
				} else
					Window.alert("Empty value was selected");
			}
		});
	}

	@SuppressWarnings("deprecation")
	public void createAnatomicEntity(AnatomicEntityAIMTemplate anatomicEntity) {
		// check if the anatomicEntity is null and exit or not
		if (anatomicEntity == null)
			return;
		VerticalPanel v = new VerticalPanel();
		if (anatomicEntity.isAnnotatorConfidence()) {
			final DoubleBox confidence = new DoubleBox();
			confidence.setValue(0.0);
			// add maximum and minimum number (0.0 to 1.0)
			confidence.addKeyUpHandler(new KeyUpHandler() {
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (confidence.getValue() > 1)
						confidence.setValue(1.0);
					if (confidence.getValue() < 0)
						confidence.setValue(0.0);
				//	result.getAnatomicEntityAIMTemplate().setAnnatotorConfidenceValue(confidence.getValue());
				}
			});
			HorizontalPanel h = new HorizontalPanel();
			h.add((IsWidget) new Label("Confidence: "));
			h.add(confidence);
			v.add(h);
		}
		// it's auxiliary counter 
		int count = 0; 
		// cleaning the list of Anatomic Entity
//		result.getAnatomicEntityAIMTemplate().getAnoAnatomicEntityCharacteristicAIMTemplates().clear(); 
		for (final AnatomicEntityCharacteristicAIMTemplate aec : anatomicEntity.getAnoAnatomicEntityCharacteristicAIMTemplates()) {
			// adding new Anatomic Entity in the response list
//			result.getAnatomicEntityAIMTemplate().getAnoAnatomicEntityCharacteristicAIMTemplates().add(aec);
			
			final ListBox list = new ListBox();
			// this way allow to the multiple selection
			if (aec.getMaxCardinality() > 1)
				list.setMultipleSelect(true);
			
			if (aec.getMinCardinality() != 0)
				list.addItem(FIRSTELEMENT);
			for (AllowedTermAIMTemplate a : aec.getAllowedTermAIMTemplates()) {
				list.addItem(a.getCodeMeaning(), a.getCodeValue());
			}
			Label l = new Label(aec.getLabel());
			l.setTitle(aec.getExplanatoryText());
			v.add(l);
			v.add(list);
			// the final auxiliary 
			final int current = count;
			// add handler for change the result model
			list.addChangeHandler(new ChangeHandler() {
				@Override
				public void onChange(ChangeEvent event) {
					//cleaning the old selected values
					result.getAllowedTerms().clear();
					//check if the selected value was a empty value
					if (list.getSelectedIndex() != 0){
						// cleaning the AllowedTerm for the current AnatomicEntity
						//result.getResponseTemplate().getAnatomicEntityAIMTemplate().getAnatomicEntityCharacteristicAIMTemplates().get(current).getAllowedTermAIMTemplates().clear();
						// add the selected value 
						//result.getResponseTemplate().getAnatomicEntityAIMTemplate().getAnatomicEntityCharacteristicAIMTemplates().get(current).getAllowedTermAIMTemplates().add(aec.getAllowedTermAIMTemplates().get(list.getSelectedIndex()-1));
						// testing the selected value in the response list
						//Window.alert(result.getResponseTemplate().getAnatomicEntityAIMTemplate().getAnatomicEntityCharacteristicAIMTemplates().get(current).getAllowedTermAIMTemplates().get(0).getCodeMeaning());
						//Window.alert(aec.getAllowedTermAIMTemplates().get(list.getSelectedIndex()-1).getCodeMeaning() + " " + current);
					} else
						Window.alert("Empty value was selected");
				}
			});
			//increasing the counter
			count++;
		}
		CaptionPanel c = new CaptionPanel("Anatomic Entity " + anatomicEntity.getAnoAnatomicEntityCharacteristicAIMTemplates().size());
		c.add(v);
		c.setStyleName("captionComponent");
		panel.add(c);

	}


	public void createImageObservation(ImagingObservationAIMTemplate imagingObservationAIMTemplate) {
		// check if the anatomicEntity is null and exit or not
		if (imagingObservationAIMTemplate == null)
			return;
		VerticalPanel v = new VerticalPanel();
		if (imagingObservationAIMTemplate.isAnnotatorConfidence()) {
			final DoubleBox confidence = new DoubleBox();
			confidence.setValue(0.0);
			// add maximum and minimum number (0.0 to 1.0)
			confidence.addKeyUpHandler(new KeyUpHandler() {
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (confidence.getValue() > 1)
						confidence.setValue(1.0);
					if (confidence.getValue() < 0)
						confidence.setValue(0.0);
				}
			});
			HorizontalPanel h = new HorizontalPanel();
			h.add((IsWidget) new Label("Confidence: "));
			h.add(confidence);
			v.add(h);
		}
		for (ImagingObservationCharacteristicAIMTemplate i : imagingObservationAIMTemplate
				.getImagingObservationCharacteristicAIMTemplates()) {
			ListBox list = new ListBox();
			if (i.getMaxCardinality() > 1)
				list = new ListBox(true);// this way allow to the multiple
											// selection
			if (i.getMinCardinality() != 0)
				list.addItem("-------", "");
			for (AllowedTermAIMTemplate a : i.getAllowedTermAIMTemplates()) {
				list.addItem(a.getCodeMeaning(), a.getCodeValue());
			}
			Label l = new Label(i.getLabel());
			l.setTitle(i.getExplanatoryText());
			v.add(l);
			v.add(list);
		}
		CaptionPanel c = new CaptionPanel("Imaging Observation");
		c.add(v);
		c.setStyleName("captionComponent");
		panel.add(c);
	}

	public void createGeometricShape() {

	}

	public void createCalculation(CalculationTypeAIMTemplate c) {
		if (c == null)
			return;
		VerticalPanel v = new VerticalPanel();
		CaptionPanel ca = new CaptionPanel("Calculation");
		ListBox list = new ListBox();
		for (AllowedTermAIMTemplate a : c.getValidTerm()) {
			list.addItem(a.getCodeMeaning(), a.getCodeValue());
		}
		v.add(list);
		ca.add(v);
		ca.setStyleName("captionComponent");
		panel.add(ca);

	}

	public void createInference() {

	}
}
